package cn.zwk.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ProgressService {
    
    private final ConcurrentHashMap<String, ProgressInfo> progressMap = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
    public static class ProgressInfo {
        private int sent;
        private int total;
        private long lastUpdateTime;
        
        public ProgressInfo(int total) {
            this.total = total;
            this.sent = 0;
            this.lastUpdateTime = System.currentTimeMillis();
        }
        
        public synchronized void increment() {
            sent++;
            lastUpdateTime = System.currentTimeMillis();
        }
        
        public synchronized int getSent() {
            return sent;
        }
        
        public int getTotal() {
            return total;
        }
        
        public synchronized double getProgress() {
            return total > 0 ? (double) sent / total * 100 : 0;
        }
        
        public synchronized boolean isCompleted() {
            return sent >= total;
        }
        
        public synchronized long getLastUpdateTime() {
            return lastUpdateTime;
        }
    }
    
    public void initProgress(String key, int total) {
        progressMap.put(key, new ProgressInfo(total));
        log.info("初始化进度跟踪: {} -> 0/{}", key, total);
    }
    
    public void updateProgress(String key) {
        ProgressInfo info = progressMap.get(key);
        if (info != null) {
            info.increment();
        }
    }
    
    public void startProgressReporting() {
        scheduler.scheduleAtFixedRate(() -> {
            try {
                reportProgress();
            } catch (Exception e) {
                log.error("进度报告时发生错误: {}", e.getMessage(), e);
            }
        }, 1, 1, TimeUnit.SECONDS);
    }
    
    public void stopProgressReporting() {
        scheduler.shutdown();
    }
    
    private void reportProgress() {
        if (progressMap.isEmpty()) {
            return;
        }
        
        StringBuilder sb = new StringBuilder();
        sb.append("\n=== 发送进度 ===\n");
        
        boolean hasActive = false;
        for (String key : progressMap.keySet()) {
            ProgressInfo info = progressMap.get(key);
            if (info != null) {
                sb.append(String.format("%-15s: %6d/%-6d (%.1f%%)\n", 
                        key, info.getSent(), info.getTotal(), info.getProgress()));
                
                if (!info.isCompleted()) {
                    hasActive = true;
                }
            }
        }
        
        sb.append("================");
        log.info(sb.toString());
        
        // 清理已完成的任务
        progressMap.entrySet().removeIf(entry -> {
            ProgressInfo info = entry.getValue();
            return info.isCompleted() && 
                   System.currentTimeMillis() - info.getLastUpdateTime() > 5000; // 5秒后清理
        });
        
        // 如果没有活跃任务，停止报告
        if (!hasActive && progressMap.isEmpty()) {
            log.info("所有任务已完成，停止进度报告");
            stopProgressReporting();
        }
    }
    
    public void removeProgress(String key) {
        progressMap.remove(key);
    }
    
    public boolean hasActiveProgress() {
        return progressMap.values().stream().anyMatch(info -> !info.isCompleted());
    }
}